package com.ruoyi.procured.service.impl;

import java.math.BigDecimal;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.commodity.domain.ProductImage;
import com.ruoyi.commodity.mapper.ProductImageMapper;
import com.ruoyi.common.api.procuredOrders.ProcuredOrdersApi;
import com.ruoyi.common.core.domain.ProcuredOrders;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.core.domain.OrdersProduct;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.procured.domain.ProcuredPlan;
import com.ruoyi.procured.domain.ProcuredProduct;
import com.ruoyi.procured.domain.vo.ArrivedQuantityDetailsVO;
import com.ruoyi.procured.domain.vo.OrdersProductDTO;
import com.ruoyi.procured.mapper.ProcuredOrdersMapper;
import com.ruoyi.procured.mapper.ProcuredOrdersProductMapper;
import com.ruoyi.procured.mapper.ProcuredPlanMapper;
import com.ruoyi.procured.mapper.ProcuredProductMapper;
import com.ruoyi.procured.service.IProcuredOrdersService;
import com.ruoyi.sale.mapper.PlanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisServer;
import org.springframework.stereotype.Service;

import java.util.function.Function;
import java.util.stream.Collectors;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;

/**
 * 采购订单Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-11-15
 */
@Service
public class ProcuredOrdersServiceImpl implements IProcuredOrdersService, ProcuredOrdersApi
{
    @Autowired
    private ProcuredOrdersMapper procuredOrdersMapper;

    @Autowired
    private ProductImageMapper productImageMapper;

    @Autowired
    private ProcuredPlanMapper procuredPlanMapper;

    @Autowired
    private ProcuredOrdersProductMapper ordersProductMapper;

    @Autowired
    private ProcuredProductMapper procuredProductMapper;

    @Autowired
    private PlanMapper planMapper;

    /**
     * 查询采购订单
     * 
     * @param ordersId 采购订单主键
     * @return 采购订单
     */
    @Override
    public ProcuredOrders selectProcuredOrdersByOrdersId(Long ordersId) {
        // 查询采购订单信息
        ProcuredOrders procuredOrders = procuredOrdersMapper.selectByOrderId(ordersId);

        // 订单不存在则直接返回null
        if (procuredOrders == null) {
            return null;
        }

        // 根据采购订单id查询明细
        List<OrdersProduct> ordersProducts = ordersProductMapper.selectByOrdersId(Collections.singletonList(ordersId), procuredOrders.getPlanId());

        // 如果没有订单产品，直接返回订单信息
        if (ordersProducts.isEmpty()) {
            return procuredOrders;
        }

        // 收集所有产品ID
        List<Long> productIds = ordersProducts.stream()
                .map(OrdersProduct::getProductId)
                .collect(Collectors.toList());

        // 查询产品图片并按产品ID分组
        Map<Integer, List<String>> productImagesMap = productImageMapper.selectProductImagesByProductId(productIds)
                .stream()
                .collect(Collectors.groupingBy(
                        ProductImage::getProductId,
                        Collectors.mapping(ProductImage::getProductImagePath, Collectors.toList())
                ));

        // 给每个产品设置对应的图片
        ordersProducts.forEach(product -> {
            Integer productId = product.getProductId().intValue();
            List<String> imagePaths = productImagesMap.getOrDefault(productId, Collections.emptyList());
            product.setImagePath(imagePaths);
        });

        // 将产品列表设置到订单对象中（假设有这个方法，如果没有需要添加）
        procuredOrders.setOrdersProductList(ordersProducts);

        return procuredOrders;
    }


    /**
     * 查询采购订单列表
     * 
     * @param procuredOrders 采购订单
     * @return 采购订单
     */
    @Override
    public List<ProcuredOrders> selectProcuredOrdersList(ProcuredOrders procuredOrders)
    {
        List<ProcuredOrders> procuredOrdersList = procuredOrdersMapper.selectProcuredOrdersList(procuredOrders);

        // 提取所有orders_id到一个列表
        List<Long> orderIds = procuredOrdersList.stream()
                .map(ProcuredOrders::getOrdersId)
                .collect(Collectors.toList());

        // 如果orderIds为空，直接返回原列表，不执行后续查询逻辑
        if (orderIds == null || orderIds.isEmpty()) {
            return procuredOrdersList;
        }

        Map<String, Object> params = new HashMap<>();
        params.put("orderIds", orderIds);
        params.put("paymentTypes", Arrays.asList(2, 3, 4));
        params.put("reviewStatus", 2);

        //汇总未处理的驳回申请记录
        List<Map<String, Object>> resultList = procuredOrdersMapper.countGroupByOrderIds(params);
        Map<Long, Map<String, Object>> orderCountMap = new HashMap<>();
        if (resultList != null) {
            for (Map<String, Object> item : resultList) {
                Object orderIdObj = item.get("orderId");
                if (orderIdObj != null) {
                    Long orderId = Long.valueOf(orderIdObj.toString());
                    orderCountMap.put(orderId, item);
                }
            }
        }
        procuredOrdersList.forEach(order -> {
            Integer count = 0;
            Map<String, Object> data = orderCountMap.get(order.getOrdersId());
            if (data != null && data.get("count") != null) {
                count = Integer.valueOf(data.get("count").toString());
            }
            order.setSolveCount(count);
        });
        return procuredOrdersList;
    }

    @Override
    public List<ProcuredOrders> selectProcuredOrdersByList(ProcuredOrders procuredOrders) {
        List<ProcuredOrders> procuredOrdersList = procuredOrdersMapper.selectProcuredOrdersByList(procuredOrders);
        //用于修改采购订单处的入库状态的相关代码
//        procuredOrdersList.forEach(procuredOrdersObj -> {
//            if (procuredOrdersObj.getInboundNumber().equals(procuredOrdersObj.getTotal())) {
//                // 入库数量大于总数量的代码逻辑
//                procuredOrdersMapper.updateInboundStatus(Constants.STATUS_TOW,procuredOrdersObj.getOrdersId());
//            } else if (procuredOrdersObj.getInboundNumber() != 0 && procuredOrdersObj.getInboundNumber() < procuredOrdersObj.getTotal()) {
//                // 入库数量小于总数量的代码逻辑
//                procuredOrdersMapper.updateInboundStatus(Constants.STATUS_ONE,procuredOrdersObj.getOrdersId());
//            } else if (procuredOrdersObj.getInboundNumber() == 0) {
//                // 入库数量为0的代码逻辑
//                procuredOrdersMapper.updateInboundStatus(Constants.SUCCESS,procuredOrdersObj.getOrdersId());
//            }
//        });
        return procuredOrdersList;
    }

    /**
     * 新增采购订单
     * 
     * @param procuredOrders 采购订单
     * @return 结果
     */
    @Transactional
    @Override
    public int insertProcuredOrders(ProcuredOrders procuredOrders)
    {
        int rows = procuredOrdersMapper.insertProcuredOrders(procuredOrders);
        insertOrdersProduct(procuredOrders);
        return rows;
    }

    /**
     * 修改采购订单
     * 
     * @param procuredOrders 采购订单
     * @return 结果
     */
    @Transactional
    @Override
    public int updateProcuredOrders(ProcuredOrders procuredOrders)
    {
        procuredOrders.setUpdateTime(DateUtils.getNowDate());
        procuredOrdersMapper.deleteOrdersProductByOrdersId(procuredOrders.getOrdersId());
        insertOrdersProduct(procuredOrders);
        return procuredOrdersMapper.updateProcuredOrders(procuredOrders);
    }

    /**
     * 批量删除采购订单
     * 
     * @param ordersIds 需要删除的采购订单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteProcuredOrdersByOrdersIds(Long[] ordersIds)
    {
        procuredOrdersMapper.deleteOrdersProductByOrdersIds(ordersIds);
        return procuredOrdersMapper.deleteProcuredOrdersByOrdersIds(ordersIds);
    }

    /**
     * 删除采购订单信息
     * 
     * @param ordersId 采购订单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteProcuredOrdersByOrdersId(Long ordersId)
    {
        procuredOrdersMapper.deleteOrdersProductByOrdersId(ordersId);
        return procuredOrdersMapper.deleteProcuredOrdersByOrdersId(ordersId);
    }

    @Override
    public List<ProcuredOrders> selectProcuredOrdersPlanId(Long planId) {
        return procuredOrdersMapper.selectProcuredOrdersPlanId(planId);
    }

    @Override
    public int updateInboundNumber(Long ordersId) {
        return procuredOrdersMapper.updateInboundNumber(ordersId);
    }

    @Override
    public List<TreeSelect> selectProcuredOrdersTree(ProcuredOrders procuredOrders) {
        List<ProcuredOrders> procuredOrdersList = SpringUtils.getAopProxy(this).selectProcuredOrdersByList(procuredOrders);
        return buildProcuredOrdersTreeSelect(procuredOrdersList);
    }

    @Override
    public List<TreeSelect> buildProcuredOrdersTreeSelect(List<ProcuredOrders> procuredOrdersList) {
        List<ProcuredOrders> procuredOrdersTree = buildProcuredOrdersTree(procuredOrdersList);
        return procuredOrdersTree.stream().map(TreeSelect::new).collect(Collectors.toList());
    }


    @Override
    public List<ProcuredOrders> buildProcuredOrdersTree(List<ProcuredOrders> procuredOrdersList) {
        List<ProcuredOrders> returnList = new ArrayList<>();
        List<Long> collect = procuredOrdersList.stream().map(ProcuredOrders::getOrdersId).collect(Collectors.toList());
        for (ProcuredOrders procuredOrders: procuredOrdersList){
            //如果是顶节点，遍历该父节点下的所以子节的
            if(!collect.contains(procuredOrders.getParentId())){
                recursionFn(procuredOrdersList,procuredOrders);
                returnList.add(procuredOrders);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = procuredOrdersList;
        }
        return returnList;
    }

    private void recursionFn(List<ProcuredOrders> procuredOrdersList , ProcuredOrders procuredOrders){
        // 得到子节点列表
        List<ProcuredOrders> childList = getChildList(procuredOrdersList,procuredOrders);
        procuredOrders.setChildrenProcuredOrders(childList);
        for (ProcuredOrders newProcuredOrders : childList)
        {
            if (hasChild(childList, newProcuredOrders))
            {
                recursionFn(procuredOrdersList, newProcuredOrders);
            }
        }
    }

    /**
     * 获得子节点
     * @param procuredOrdersList
     * @param procuredOrders
     * @return
     */
    private List<ProcuredOrders> getChildList(List<ProcuredOrders> procuredOrdersList, ProcuredOrders procuredOrders){
        List<ProcuredOrders> returnList = new ArrayList<>();
        Iterator<ProcuredOrders> iterator = procuredOrdersList.iterator();
        while (iterator.hasNext()){
            ProcuredOrders n = (ProcuredOrders) iterator.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == procuredOrders.getOrdersId().longValue())
            {
                returnList.add(n);
            }
        }
        return returnList;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<ProcuredOrders> procuredOrdersList, ProcuredOrders procuredOrders)
    {
        return getChildList(procuredOrdersList, procuredOrders).size() > 0;
    }


    @Override
    public ProcuredOrders selectOrdersNumber(String ordersId) {
        return procuredOrdersMapper.selectOrdersNumber(ordersId);
    }

    @Override
    public int updateExpressNumber(ProcuredOrders procuredOrders) {
        return procuredOrdersMapper.updateExpressNumber(procuredOrders);
    }

    @Override
    public List<ArrivedQuantityDetailsVO> getArrivedQuantityDetails(ArrivedQuantityDetailsVO vo) {
        if(vo.getProductId() == null){
            throw new ServiceException("请传入对应的产品id!");
        }
        List<ArrivedQuantityDetailsVO> arrivedQuantityDetails = procuredOrdersMapper.getArrivedQuantityDetails(vo);
        // 提取 productIds
        List<Long> productIds = arrivedQuantityDetails.stream()
                .map(ArrivedQuantityDetailsVO::getProductId)
                .collect(Collectors.toList());


        if (productIds.isEmpty() || arrivedQuantityDetails.isEmpty()) {
            return new ArrayList<>();
        }


        Map<Integer, List<String>> collect = productImageMapper.selectProductImagesByProductId(productIds)
                .stream()
                .collect(Collectors.groupingBy(ProductImage::getProductId,
                        Collectors.mapping(ProductImage::getProductImagePath, Collectors.toList())));


        arrivedQuantityDetails.forEach(item -> {
            List<String> imagePath = collect.getOrDefault(item.getProductId().intValue(), new ArrayList<>());
            item.setProductImagePath(imagePath);
        });
        return arrivedQuantityDetails;
    }

    /**
     * 查询该申请的采购订单数据（商品信息，入库，出库信息）
     * @param ordersId
     * @return
     */
    @Override
    public List<OrdersProductDTO> selectOrdersProductListByOrdersId(Long ordersId) {
        return procuredOrdersMapper.selectOrdersProductListByOrdersId(ordersId);
    }
    /**
     * 撤回采购单订单
     * @return
     */
    @Override
    @Transactional
    public int revokeProcuredOrders(Long procuredOrderId, String revokeRemark, String nickname) {

        //更新采购订单状态
        ProcuredOrders  procuredOrders = procuredOrdersMapper.selectProcuredOrdersByOrdersId(procuredOrderId);
        procuredOrders.setDeleteStatus("1");
        procuredOrders.setRevokeRemark(revokeRemark);
        procuredOrdersMapper.updateProcuredOrders(procuredOrders);

        // 根据采购订单id查询明细
        List<OrdersProduct> ordersProducts = ordersProductMapper.selectByOrdersId(Collections.singletonList(procuredOrderId), procuredOrders.getPlanId());

        //获取采购计划明细
        Long planId = procuredOrders.getPlanId();

        // 构建产品ID列表
        List<Long> productIds = ordersProducts.stream()
                .map(OrdersProduct::getProductId)
                .collect(Collectors.toList());

        // 批量查询采购计划明细
        List<ProcuredProduct> procuredProducts = procuredProductMapper.selectList(
                new LambdaQueryWrapper<ProcuredProduct>()
                        .in(ProcuredProduct::getProductId, productIds)
                        .eq(ProcuredProduct::getPlanId, planId)
        );

        // 创建产品ID到采购计划明细的映射
        Map<Integer, ProcuredProduct> productMap = procuredProducts.stream()
                .collect(Collectors.toMap(ProcuredProduct::getProductId, Function.identity()));

        // 准备批量更新的数据
        List<ProcuredProduct> updateList = new ArrayList<>();
        for (OrdersProduct ordersProduct : ordersProducts) {
            // TODO 查询当前撤回的采购订单中的订单商品是否已经被提前结束了
            ProcuredProduct procuredProduct = productMap.get(ordersProduct.getProductId().intValue());
            if (procuredProduct != null) {
                // 计算回滚后的数量
                Long transferableNumber = ordersProduct.getTransferableNumber();
                Integer oldTurnedNumber = procuredProduct.getTurnedNumber();
                Integer oldTransferableNumber = procuredProduct.getTransferableNumber();
                Integer totalNumber = procuredProduct.getNumber();

                // 回滚计算
                Integer newTurnedNumber = oldTurnedNumber - transferableNumber.intValue();
                Integer newTransferableNumber = oldTransferableNumber + transferableNumber.intValue();

                // 数据一致性校验
                Integer sum = newTurnedNumber + newTransferableNumber;
                if (!sum.equals(totalNumber)) {
                    throw new RuntimeException(String.format(
                            "数据不一致：产品ID[%s]，已转数量[%s] + 可转数量[%s] = [%s]，总数量[%s]",
                            ordersProduct.getProductId(), newTurnedNumber, newTransferableNumber, sum, totalNumber));
                }

                // 创建更新对象
                ProcuredProduct updateProduct = new ProcuredProduct();
                updateProduct.setId(procuredProduct.getId()); // 需要主键进行更新
                updateProduct.setTurnedNumber(newTurnedNumber);
                updateProduct.setTransferableNumber(newTransferableNumber);

                updateList.add(updateProduct);
            }
        }
        int rows = 0;
        // 批量更新
        if (!updateList.isEmpty()) {
            rows = procuredProductMapper.batchUpdateNumbers(updateList);
        }
        // 更新完采购计划明细后，汇总判断采购计划状态
        if (rows > 0) {
            // 查询该采购计划下所有明细的turned_number总和
            List<ProcuredProduct> allPlanProducts = procuredProductMapper.selectList(
                    new LambdaQueryWrapper<ProcuredProduct>()
                            .eq(ProcuredProduct::getPlanId, planId)
            );

            // 汇总所有明细的turned_number
            int totalTurnedNumber = allPlanProducts.stream()
                    .mapToInt(product -> product.getTurnedNumber() != null ? product.getTurnedNumber() : 0)
                    .sum();

            // 根据汇总结果确定采购计划状态
            String planStatus = (totalTurnedNumber == 0) ? "1" : "2";

            // 更新采购计划状态
            ProcuredPlan procuredPlan = new ProcuredPlan();
            procuredPlan.setPlanId(planId);
            procuredPlan.setPlanStatus(planStatus);
            procuredPlanMapper.updateById(procuredPlan); // 或者使用您的更新方法
        }
        return rows;
    }

    /**
     * 查询未被收货过的采购订单
     * @param procuredOrders
     * @return
     */
//    @Override
//    public List<ProcuredOrders> selectProcuredUnreceivedOrders(ProcuredOrders procuredOrders) {
//        List<ProcuredOrders> procuredOrdersList = procuredOrdersMapper.selectProcuredUnreceivedOrders(procuredOrders);
//        return procuredOrdersList;
//    }

    /**
     * 新增采购订单商品信息
     * 
     * @param procuredOrders 采购订单对象
     */
    public void insertOrdersProduct(ProcuredOrders procuredOrders)
    {
        List<OrdersProduct> ordersProductList = procuredOrders.getOrdersProductList();
        Long ordersId = procuredOrders.getOrdersId();
        if (StringUtils.isNotNull(ordersProductList))
        {
            List<OrdersProduct> list = new ArrayList<OrdersProduct>();
            for (OrdersProduct ordersProduct : ordersProductList)
            {

                ordersProduct.setOrdersId(ordersId);
                list.add(ordersProduct);
            }
            if (list.size() > 0)
            {
                procuredOrdersMapper.batchOrdersProduct(list);
            }
        }
    }

    @Override
    public int updateStyleClass(List<Long> planIds, Long productId) {
        return procuredOrdersMapper.updateStyleClass(planIds,productId);
    }

    @Override
    public List<ProcuredOrders> selectOrdersId(List<Long> planIds, Long productId) {
        return procuredOrdersMapper.selectByOrderIds(planIds,productId);
    }
}